package com.strong.utils.mvc.pojo.view;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.strong.utils.JSON;
import lombok.Data;

/**
 * 用于与前端交互的统一泛型对象
 *
 * @param <M> 装载的数据类型
 * @author Simen
 * @version 1.0
 */
@Data
public class ReplyVO<M> {

    /**
     * resultful 的规范，后端返回 JSON 数据的约定（vab 2021 年 4 月 15 日后版本）
     * <pre>
     * {
     *   "code": 200, //成功的状态码
     *   "msg": "success", //提示信息
     *   "data": { //返回数据
     *       "list": [{}，{}，{}], //返回数组
     *       "total": 238, //总条数（表格中用到，其它接口可以不返回）
     *   }
     * }
     * </pre>
     */

    /**
     * 提示信息
     */
    private String msg;

    /**
     * 成功的状态码
     */
    private Integer code;

    /**
     * 返回数据
     */
    private M data;

    /**
     * 实例化
     */
    public ReplyVO() {
        this(null, ReplyEnum.SUCCESS_RETURN_DATA);
    }

    /**
     * 实例化
     *
     * @param replyEnum 回复枚举
     */
    public ReplyVO(ReplyEnum replyEnum) {
        this(null, replyEnum);
    }

    /**
     * 实例化
     * correct
     *
     * @param data 数据
     */
    public ReplyVO(M data) {
        this(data, ReplyEnum.SUCCESS_RETURN_DATA);
    }

    /**
     * 实例化
     *
     * @param data      数据
     * @param replyEnum 回复枚举
     */
    public ReplyVO(M data, ReplyEnum replyEnum) {
        this(data, replyEnum.getMsg(), replyEnum.getCode());
    }

    /**
     * 实例化
     *
     * @param data 数据
     * @param code 代码
     */
    public ReplyVO(M data, Integer code) {
        this.msg = data.toString();
        this.code = code;
        this.data = data;
    }

    /**
     * 实例化
     *
     * @param data 数据
     * @param msg  消息
     */
    public ReplyVO(M data, String msg) {
        this(data, msg, ReplyEnum.SUCCESS_RETURN_DATA.getCode());
    }

    /**
     * 实例化
     *
     * @param data 数据
     * @param msg  消息
     * @param code 代码
     */
    public ReplyVO(M data, String msg, Integer code) {
        if (ObjUtil.isNull(data)) {
            this.data = (M) msg;
            this.msg = msg;
        } else {
            this.data = data;
            if (StrUtil.isBlank(msg) && ObjUtil.isNotNull(data)) {
                this.msg = data.toString();
            } else {
                this.msg = msg;
            }
        }

        this.code = code;
    }

    public String toString() {
        return JSON.toJSONString(this, true);
    }
}
